Skip to content

fix: validate cached validator indices against state - #9748

Merged
nflaig merged 1 commit into
unstablefrom
nflaig/validate-cached-validator-indices
Aug 3, 2026
Merged

fix: validate cached validator indices against state#9748
nflaig merged 1 commit into
unstablefrom
nflaig/validate-cached-validator-indices

Conversation

@nflaig

@nflaig nflaig commented Aug 2, 2026

Copy link
Copy Markdown
Member

No description provided.

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: b27a05e Previous: b3cb0f6 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 906.58 us/op 1.0484 ms/op 0.86
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 37.390 us/op 40.844 us/op 0.92
BLS verify - blst 716.41 us/op 662.34 us/op 1.08
BLS verifyMultipleSignatures 3 - blst 1.3515 ms/op 1.3852 ms/op 0.98
BLS verifyMultipleSignatures 8 - blst 2.1450 ms/op 2.2027 ms/op 0.97
BLS verifyMultipleSignatures 32 - blst 6.8005 ms/op 6.9396 ms/op 0.98
BLS verifyMultipleSignatures 64 - blst 13.369 ms/op 13.781 ms/op 0.97
BLS verifyMultipleSignatures 128 - blst 25.995 ms/op 26.020 ms/op 1.00
BLS deserializing 10000 signatures 614.95 ms/op 642.55 ms/op 0.96
BLS deserializing 100000 signatures 6.0977 s/op 6.4661 s/op 0.94
BLS verifyMultipleSignatures - same message - 3 - blst 688.71 us/op 798.28 us/op 0.86
BLS verifyMultipleSignatures - same message - 8 - blst 811.79 us/op 948.21 us/op 0.86
BLS verifyMultipleSignatures - same message - 32 - blst 1.4397 ms/op 1.4735 ms/op 0.98
BLS verifyMultipleSignatures - same message - 64 - blst 2.2327 ms/op 2.3872 ms/op 0.94
BLS verifyMultipleSignatures - same message - 128 - blst 3.8457 ms/op 4.1394 ms/op 0.93
BLS aggregatePubkeys 32 - blst 16.728 us/op 17.809 us/op 0.94
BLS aggregatePubkeys 128 - blst 59.635 us/op 63.908 us/op 0.93
getSlashingsAndExits - default max 41.139 us/op 49.481 us/op 0.83
getSlashingsAndExits - 2k 323.41 us/op 353.29 us/op 0.92
proposeBlockBody type=full, size=empty 613.97 us/op 640.40 us/op 0.96
isKnown best case - 1 super set check 186.00 ns/op 170.00 ns/op 1.09
isKnown normal case - 2 super set checks 161.00 ns/op 165.00 ns/op 0.98
isKnown worse case - 16 super set checks 164.00 ns/op 169.00 ns/op 0.97
validate api signedAggregateAndProof - struct 1.4962 ms/op 1.5601 ms/op 0.96
validate gossip signedAggregateAndProof - struct 1.4988 ms/op 1.5566 ms/op 0.96
batch validate gossip attestation - vc 640000 - chunk 32 102.25 us/op 111.02 us/op 0.92
batch validate gossip attestation - vc 640000 - chunk 64 89.433 us/op 95.224 us/op 0.94
batch validate gossip attestation - vc 640000 - chunk 128 83.556 us/op 89.225 us/op 0.94
batch validate gossip attestation - vc 640000 - chunk 256 80.187 us/op 84.843 us/op 0.95
bytes32 toHexString 294.00 ns/op 292.00 ns/op 1.01
bytes32 Buffer.toString(hex) 155.00 ns/op 165.00 ns/op 0.94
bytes32 Buffer.toString(hex) from Uint8Array 227.00 ns/op 235.00 ns/op 0.97
bytes32 Buffer.toString(hex) + 0x 157.00 ns/op 165.00 ns/op 0.95
Return object 10000 times 0.20420 ns/op 0.21320 ns/op 0.96
Throw Error 10000 times 3.2344 us/op 3.4972 us/op 0.92
toHex 95.390 ns/op 100.52 ns/op 0.95
Buffer.from 80.063 ns/op 93.044 ns/op 0.86
shared Buffer 56.918 ns/op 64.170 ns/op 0.89
fastMsgIdFn sha256 / 200 bytes 1.3940 us/op 1.4950 us/op 0.93
fastMsgIdFn h32 xxhash / 200 bytes 147.00 ns/op 150.00 ns/op 0.98
fastMsgIdFn h64 xxhash / 200 bytes 183.00 ns/op 209.00 ns/op 0.88
fastMsgIdFn sha256 / 1000 bytes 4.4560 us/op 4.9010 us/op 0.91
fastMsgIdFn h32 xxhash / 1000 bytes 235.00 ns/op 240.00 ns/op 0.98
fastMsgIdFn h64 xxhash / 1000 bytes 238.00 ns/op 257.00 ns/op 0.93
fastMsgIdFn sha256 / 10000 bytes 39.261 us/op 43.245 us/op 0.91
fastMsgIdFn h32 xxhash / 10000 bytes 1.2090 us/op 1.2670 us/op 0.95
fastMsgIdFn h64 xxhash / 10000 bytes 798.00 ns/op 819.00 ns/op 0.97
send data - 1000 256B messages 4.0364 ms/op 4.1424 ms/op 0.97
send data - 1000 512B messages 5.2804 ms/op 4.9397 ms/op 1.07
send data - 1000 1024B messages 5.5812 ms/op 5.6226 ms/op 0.99
send data - 1000 1200B messages 6.2307 ms/op 6.0369 ms/op 1.03
send data - 1000 2048B messages 8.4021 ms/op 20.242 ms/op 0.42
send data - 1000 4096B messages 56.256 ms/op 47.211 ms/op 1.19
send data - 1000 16384B messages 278.74 ms/op 255.66 ms/op 1.09
send data - 1000 65536B messages 1.5533 s/op 1.2293 s/op 1.26
enrSubnets - fastDeserialize 64 bits 709.00 ns/op 784.00 ns/op 0.90
enrSubnets - ssz BitVector 64 bits 263.00 ns/op 266.00 ns/op 0.99
enrSubnets - fastDeserialize 4 bits 94.000 ns/op 104.00 ns/op 0.90
enrSubnets - ssz BitVector 4 bits 267.00 ns/op 269.00 ns/op 0.99
prioritizePeers score -10:0 att 32-0.1 sync 2-0 206.62 us/op 212.78 us/op 0.97
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 215.57 us/op 243.12 us/op 0.89
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 324.29 us/op 353.36 us/op 0.92
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 581.61 us/op 621.30 us/op 0.94
prioritizePeers score 0:0 att 64-1 sync 4-1 678.09 us/op 727.66 us/op 0.93
array of 16000 items push then shift 1.2828 us/op 1.3198 us/op 0.97
LinkedList of 16000 items push then shift 7.0330 ns/op 6.9230 ns/op 1.02
array of 16000 items push then pop 62.690 ns/op 66.659 ns/op 0.94
LinkedList of 16000 items push then pop 5.6230 ns/op 6.1480 ns/op 0.91
array of 24000 items push then shift 1.7346 us/op 1.9636 us/op 0.88
LinkedList of 24000 items push then shift 6.6400 ns/op 6.4990 ns/op 1.02
array of 24000 items push then pop 87.172 ns/op 93.766 ns/op 0.93
LinkedList of 24000 items push then pop 5.6830 ns/op 6.1320 ns/op 0.93
intersect bitArray bitLen 8 3.6540 ns/op 3.9010 ns/op 0.94
intersect array and set length 8 54.042 ns/op 30.630 ns/op 1.76
intersect bitArray bitLen 128 21.862 ns/op 23.527 ns/op 0.93
intersect array and set length 128 464.14 ns/op 517.67 ns/op 0.90
bitArray.getTrueBitIndexes() bitLen 128 878.00 ns/op 931.00 ns/op 0.94
bitArray.getTrueBitIndexes() bitLen 248 1.5960 us/op 1.6660 us/op 0.96
bitArray.getTrueBitIndexes() bitLen 512 3.3440 us/op 3.4810 us/op 0.96
Full columns - reconstruct all 6 blobs 168.53 us/op 165.69 us/op 1.02
Full columns - reconstruct half of the blobs out of 6 67.228 us/op 68.287 us/op 0.98
Full columns - reconstruct single blob out of 6 34.811 us/op 33.919 us/op 1.03
Half columns - reconstruct all 6 blobs 377.31 ms/op 396.72 ms/op 0.95
Half columns - reconstruct half of the blobs out of 6 193.11 ms/op 203.65 ms/op 0.95
Half columns - reconstruct single blob out of 6 69.294 ms/op 70.710 ms/op 0.98
Set add up to 64 items then delete first 2.1525 us/op 1.6887 us/op 1.27
OrderedSet add up to 64 items then delete first 3.3241 us/op 2.5696 us/op 1.29
Set add up to 64 items then delete last 2.3389 us/op 1.9749 us/op 1.18
OrderedSet add up to 64 items then delete last 3.2480 us/op 3.0060 us/op 1.08
Set add up to 64 items then delete middle 2.1089 us/op 2.0226 us/op 1.04
OrderedSet add up to 64 items then delete middle 4.6871 us/op 4.5528 us/op 1.03
Set add up to 128 items then delete first 4.2012 us/op 3.9387 us/op 1.07
OrderedSet add up to 128 items then delete first 6.4373 us/op 5.8714 us/op 1.10
Set add up to 128 items then delete last 3.8374 us/op 3.8884 us/op 0.99
OrderedSet add up to 128 items then delete last 5.7120 us/op 5.9316 us/op 0.96
Set add up to 128 items then delete middle 3.8170 us/op 3.8388 us/op 0.99
OrderedSet add up to 128 items then delete middle 11.500 us/op 11.878 us/op 0.97
Set add up to 256 items then delete first 7.8265 us/op 7.9006 us/op 0.99
OrderedSet add up to 256 items then delete first 11.982 us/op 12.067 us/op 0.99
Set add up to 256 items then delete last 7.4597 us/op 7.7172 us/op 0.97
OrderedSet add up to 256 items then delete last 11.357 us/op 12.126 us/op 0.94
Set add up to 256 items then delete middle 7.5140 us/op 7.6175 us/op 0.99
OrderedSet add up to 256 items then delete middle 34.462 us/op 35.825 us/op 0.96
runFastConfirmationRules vc:100000 bc:96 eq:0 4.9335 ms/op 5.1926 ms/op 0.95
runFastConfirmationRules vc:600000 bc:96 eq:0 39.187 ms/op 35.686 ms/op 1.10
runFastConfirmationRules vc:1000000 bc:96 eq:0 66.237 ms/op 59.620 ms/op 1.11
runFastConfirmationRules vc:600000 bc:320 eq:0 37.152 ms/op 35.735 ms/op 1.04
runFastConfirmationRules vc:100000 bc:96 eq:1000 1.0403 s/op 1.1033 s/op 0.94
pass gossip attestations to forkchoice per slot 2.5415 ms/op 2.6199 ms/op 0.97
forkChoice updateHead vc 100000 bc 64 eq 0 450.72 us/op 478.91 us/op 0.94
forkChoice updateHead vc 600000 bc 64 eq 0 2.3286 ms/op 2.7665 ms/op 0.84
forkChoice updateHead vc 1000000 bc 64 eq 0 3.8265 ms/op 4.6805 ms/op 0.82
forkChoice updateHead vc 600000 bc 320 eq 0 2.2756 ms/op 2.8882 ms/op 0.79
forkChoice updateHead vc 600000 bc 1200 eq 0 2.3684 ms/op 2.9500 ms/op 0.80
forkChoice updateHead vc 600000 bc 7200 eq 0 2.6601 ms/op 3.2581 ms/op 0.82
forkChoice updateHead vc 600000 bc 64 eq 1000 2.2675 ms/op 2.8826 ms/op 0.79
forkChoice updateHead vc 600000 bc 64 eq 10000 2.3796 ms/op 2.8364 ms/op 0.84
forkChoice updateHead vc 600000 bc 64 eq 300000 5.9781 ms/op 6.7289 ms/op 0.89
computeDeltas 1400000 validators 0% inactive 11.395 ms/op 13.518 ms/op 0.84
computeDeltas 1400000 validators 10% inactive 10.906 ms/op 12.777 ms/op 0.85
computeDeltas 1400000 validators 20% inactive 10.065 ms/op 12.095 ms/op 0.83
computeDeltas 1400000 validators 50% inactive 8.2915 ms/op 9.8352 ms/op 0.84
computeDeltas 2100000 validators 0% inactive 16.915 ms/op 20.162 ms/op 0.84
computeDeltas 2100000 validators 10% inactive 15.996 ms/op 19.316 ms/op 0.83
computeDeltas 2100000 validators 20% inactive 14.989 ms/op 17.943 ms/op 0.84
computeDeltas 2100000 validators 50% inactive 10.034 ms/op 14.621 ms/op 0.69
altair processAttestation - 250000 vs - 7PWei normalcase 1.6609 ms/op 1.6198 ms/op 1.03
altair processAttestation - 250000 vs - 7PWei worstcase 2.4017 ms/op 2.3987 ms/op 1.00
altair processAttestation - setStatus - 1/6 committees join 108.21 us/op 106.13 us/op 1.02
altair processAttestation - setStatus - 1/3 committees join 205.18 us/op 202.89 us/op 1.01
altair processAttestation - setStatus - 1/2 committees join 283.98 us/op 287.01 us/op 0.99
altair processAttestation - setStatus - 2/3 committees join 367.91 us/op 368.76 us/op 1.00
altair processAttestation - setStatus - 4/5 committees join 512.31 us/op 510.32 us/op 1.00
altair processAttestation - setStatus - 100% committees join 596.87 us/op 602.03 us/op 0.99
altair processBlock - 250000 vs - 7PWei normalcase 3.2106 ms/op 3.2142 ms/op 1.00
altair processBlock - 250000 vs - 7PWei normalcase hashState 14.427 ms/op 12.444 ms/op 1.16
altair processBlock - 250000 vs - 7PWei worstcase 20.162 ms/op 19.820 ms/op 1.02
altair processBlock - 250000 vs - 7PWei worstcase hashState 42.176 ms/op 38.508 ms/op 1.10
phase0 processBlock - 250000 vs - 7PWei normalcase 1.3547 ms/op 1.3453 ms/op 1.01
phase0 processBlock - 250000 vs - 7PWei worstcase 17.212 ms/op 17.320 ms/op 0.99
altair processEth1Data - 250000 vs - 7PWei normalcase 292.85 us/op 311.55 us/op 0.94
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 3.2020 us/op 3.7080 us/op 0.86
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 19.201 us/op 23.362 us/op 0.82
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 5.4580 us/op 6.5680 us/op 0.83
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 3.3090 us/op 5.2240 us/op 0.63
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 90.156 us/op 100.30 us/op 0.90
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.3547 ms/op 1.4170 ms/op 0.96
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.7039 ms/op 1.9115 ms/op 0.89
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 1.7507 ms/op 1.8619 ms/op 0.94
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 3.5430 ms/op 3.7932 ms/op 0.93
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.0726 ms/op 2.0805 ms/op 1.00
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 3.7327 ms/op 4.0441 ms/op 0.92
Tree 40 250000 create 331.81 ms/op 320.02 ms/op 1.04
Tree 40 250000 get(125000) 100.06 ns/op 103.87 ns/op 0.96
Tree 40 250000 set(125000) 1.0263 us/op 1.0979 us/op 0.93
Tree 40 250000 toArray() 10.749 ms/op 9.6388 ms/op 1.12
Tree 40 250000 iterate all - toArray() + loop 9.3767 ms/op 9.7342 ms/op 0.96
Tree 40 250000 iterate all - get(i) 38.236 ms/op 37.194 ms/op 1.03
Array 250000 create 2.0829 ms/op 2.0605 ms/op 1.01
Array 250000 clone - spread 645.37 us/op 648.88 us/op 0.99
Array 250000 get(125000) 0.28400 ns/op 0.29800 ns/op 0.95
Array 250000 set(125000) 0.28500 ns/op 0.30300 ns/op 0.94
Array 250000 iterate all - loop 55.523 us/op 57.337 us/op 0.97
phase0 afterProcessEpoch - 250000 vs - 7PWei 52.737 ms/op 39.436 ms/op 1.34
Array.fill - length 1000000 2.1916 ms/op 2.3815 ms/op 0.92
Array push - length 1000000 7.4826 ms/op 7.6183 ms/op 0.98
Array.get 0.20262 ns/op 0.20628 ns/op 0.98
Uint8Array.get 0.22520 ns/op 0.24774 ns/op 0.91
phase0 beforeProcessEpoch - 250000 vs - 7PWei 17.692 ms/op 12.241 ms/op 1.45
altair processEpoch - mainnet_e81889 227.94 ms/op 245.23 ms/op 0.93
mainnet_e81889 - altair beforeProcessEpoch 33.491 ms/op 19.548 ms/op 1.71
mainnet_e81889 - altair processJustificationAndFinalization 5.5660 us/op 5.1910 us/op 1.07
mainnet_e81889 - altair processInactivityUpdates 3.4632 ms/op 3.7644 ms/op 0.92
mainnet_e81889 - altair processRewardsAndPenalties 18.682 ms/op 17.382 ms/op 1.07
mainnet_e81889 - altair processRegistryUpdates 562.00 ns/op 587.00 ns/op 0.96
mainnet_e81889 - altair processSlashings 137.00 ns/op 160.00 ns/op 0.86
mainnet_e81889 - altair processEth1DataReset 132.00 ns/op 155.00 ns/op 0.85
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.5062 ms/op 1.7260 ms/op 0.87
mainnet_e81889 - altair processSlashingsReset 687.00 ns/op 714.00 ns/op 0.96
mainnet_e81889 - altair processRandaoMixesReset 971.00 ns/op 1.0960 us/op 0.89
mainnet_e81889 - altair processHistoricalRootsUpdate 135.00 ns/op 155.00 ns/op 0.87
mainnet_e81889 - altair processParticipationFlagUpdates 436.00 ns/op 462.00 ns/op 0.94
mainnet_e81889 - altair processSyncCommitteeUpdates 107.00 ns/op 130.00 ns/op 0.82
mainnet_e81889 - altair afterProcessEpoch 41.937 ms/op 40.583 ms/op 1.03
capella processEpoch - mainnet_e217614 789.77 ms/op 817.04 ms/op 0.97
mainnet_e217614 - capella beforeProcessEpoch 54.599 ms/op 59.005 ms/op 0.93
mainnet_e217614 - capella processJustificationAndFinalization 4.9420 us/op 5.6370 us/op 0.88
mainnet_e217614 - capella processInactivityUpdates 11.900 ms/op 12.247 ms/op 0.97
mainnet_e217614 - capella processRewardsAndPenalties 96.015 ms/op 96.748 ms/op 0.99
mainnet_e217614 - capella processRegistryUpdates 4.5040 us/op 4.5700 us/op 0.99
mainnet_e217614 - capella processSlashings 136.00 ns/op 147.00 ns/op 0.93
mainnet_e217614 - capella processEth1DataReset 134.00 ns/op 146.00 ns/op 0.92
mainnet_e217614 - capella processEffectiveBalanceUpdates 6.3404 ms/op 5.9866 ms/op 1.06
mainnet_e217614 - capella processSlashingsReset 670.00 ns/op 694.00 ns/op 0.97
mainnet_e217614 - capella processRandaoMixesReset 990.00 ns/op 1.3210 us/op 0.75
mainnet_e217614 - capella processHistoricalRootsUpdate 136.00 ns/op 155.00 ns/op 0.88
mainnet_e217614 - capella processParticipationFlagUpdates 447.00 ns/op 467.00 ns/op 0.96
mainnet_e217614 - capella afterProcessEpoch 108.20 ms/op 109.96 ms/op 0.98
phase0 processEpoch - mainnet_e58758 296.17 ms/op 315.15 ms/op 0.94
mainnet_e58758 - phase0 beforeProcessEpoch 64.655 ms/op 71.026 ms/op 0.91
mainnet_e58758 - phase0 processJustificationAndFinalization 6.0980 us/op 6.5470 us/op 0.93
mainnet_e58758 - phase0 processRewardsAndPenalties 15.740 ms/op 16.802 ms/op 0.94
mainnet_e58758 - phase0 processRegistryUpdates 2.3030 us/op 2.3240 us/op 0.99
mainnet_e58758 - phase0 processSlashings 136.00 ns/op 157.00 ns/op 0.87
mainnet_e58758 - phase0 processEth1DataReset 331.00 ns/op 156.00 ns/op 2.12
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 799.57 us/op 1.3485 ms/op 0.59
mainnet_e58758 - phase0 processSlashingsReset 856.00 ns/op 931.00 ns/op 0.92
mainnet_e58758 - phase0 processRandaoMixesReset 1.3660 us/op 1.3170 us/op 1.04
mainnet_e58758 - phase0 processHistoricalRootsUpdate 136.00 ns/op 161.00 ns/op 0.84
mainnet_e58758 - phase0 processParticipationRecordUpdates 1.2630 us/op 1.1530 us/op 1.10
mainnet_e58758 - phase0 afterProcessEpoch 34.237 ms/op 34.029 ms/op 1.01
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.1020 ms/op 1.0407 ms/op 1.06
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 1.6282 ms/op 1.6731 ms/op 0.97
altair processInactivityUpdates - 250000 normalcase 10.475 ms/op 10.910 ms/op 0.96
altair processInactivityUpdates - 250000 worstcase 10.622 ms/op 10.626 ms/op 1.00
phase0 processRegistryUpdates - 250000 normalcase 2.3390 us/op 2.4390 us/op 0.96
phase0 processRegistryUpdates - 250000 badcase_full_deposits 147.24 us/op 144.99 us/op 1.02
phase0 processRegistryUpdates - 250000 worstcase 0.5 71.678 ms/op 51.709 ms/op 1.39
altair processRewardsAndPenalties - 250000 normalcase 14.654 ms/op 15.201 ms/op 0.96
altair processRewardsAndPenalties - 250000 worstcase 14.278 ms/op 15.602 ms/op 0.92
phase0 getAttestationDeltas - 250000 normalcase 5.1497 ms/op 5.4159 ms/op 0.95
phase0 getAttestationDeltas - 250000 worstcase 5.1807 ms/op 5.5034 ms/op 0.94
phase0 processSlashings - 250000 worstcase 57.853 us/op 62.399 us/op 0.93
altair processSyncCommitteeUpdates - 250000 9.7519 ms/op 10.201 ms/op 0.96
BeaconState.hashTreeRoot - No change 163.00 ns/op 191.00 ns/op 0.85
BeaconState.hashTreeRoot - 1 full validator 71.715 us/op 57.076 us/op 1.26
BeaconState.hashTreeRoot - 32 full validator 982.15 us/op 719.35 us/op 1.37
BeaconState.hashTreeRoot - 512 full validator 6.4433 ms/op 5.9999 ms/op 1.07
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 102.19 us/op 70.494 us/op 1.45
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.5912 ms/op 1.0456 ms/op 1.52
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 18.153 ms/op 12.820 ms/op 1.42
BeaconState.hashTreeRoot - 1 balances 99.319 us/op 55.867 us/op 1.78
BeaconState.hashTreeRoot - 32 balances 717.93 us/op 540.14 us/op 1.33
BeaconState.hashTreeRoot - 512 balances 5.6650 ms/op 4.6233 ms/op 1.23
BeaconState.hashTreeRoot - 250000 balances 162.50 ms/op 89.826 ms/op 1.81
aggregationBits - 2048 els - zipIndexesInBitList 19.803 us/op 20.194 us/op 0.98
regular array get 100000 times 22.919 us/op 22.932 us/op 1.00
wrappedArray get 100000 times 22.909 us/op 22.929 us/op 1.00
arrayWithProxy get 100000 times 12.449 ms/op 10.719 ms/op 1.16
ssz.Root.equals 21.409 ns/op 21.536 ns/op 0.99
byteArrayEquals 21.307 ns/op 21.362 ns/op 1.00
Buffer.compare 8.7910 ns/op 9.6450 ns/op 0.91
processSlot - 1 slots 8.8210 us/op 8.2710 us/op 1.07
processSlot - 32 slots 2.1574 ms/op 1.8571 ms/op 1.16
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 7.1103 ms/op 2.8854 ms/op 2.46
getCommitteeAssignments - req 1 vs - 250000 vc 1.6475 ms/op 1.6924 ms/op 0.97
getCommitteeAssignments - req 100 vs - 250000 vc 3.3987 ms/op 3.4554 ms/op 0.98
getCommitteeAssignments - req 1000 vs - 250000 vc 3.6393 ms/op 3.7095 ms/op 0.98
findModifiedValidators - 10000 modified validators 653.68 ms/op 661.28 ms/op 0.99
findModifiedValidators - 1000 modified validators 466.84 ms/op 556.43 ms/op 0.84
findModifiedValidators - 100 modified validators 257.49 ms/op 323.50 ms/op 0.80
findModifiedValidators - 10 modified validators 142.98 ms/op 279.33 ms/op 0.51
findModifiedValidators - 1 modified validators 170.27 ms/op 241.05 ms/op 0.71
findModifiedValidators - no difference 150.61 ms/op 204.13 ms/op 0.74
migrate state 1500000 validators, 3400 modified, 2000 new 3.4232 s/op 2.6743 s/op 1.28
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 3.4900 ns/op 3.8700 ns/op 0.90
state getBlockRootAtSlot - 250000 vs - 7PWei 454.77 ns/op 287.05 ns/op 1.58
computeProposerIndex 100000 validators 1.3224 ms/op 1.3246 ms/op 1.00
getNextSyncCommitteeIndices 1000 validators 2.8142 ms/op 2.8825 ms/op 0.98
getNextSyncCommitteeIndices 10000 validators 25.014 ms/op 25.180 ms/op 0.99
getNextSyncCommitteeIndices 100000 validators 82.702 ms/op 83.309 ms/op 0.99
computeProposers - vc 250000 536.95 us/op 549.11 us/op 0.98
computeEpochShuffling - vc 250000 40.365 ms/op 40.507 ms/op 1.00
getNextSyncCommittee - vc 250000 9.2849 ms/op 9.4038 ms/op 0.99
nodejs block root to RootHex using toHex 97.507 ns/op 104.82 ns/op 0.93
nodejs block root to RootHex using toRootHex 67.345 ns/op 69.665 ns/op 0.97
nodejs fromHex(blob) 796.99 us/op 809.38 us/op 0.98
nodejs fromHexInto(blob) 739.82 us/op 668.08 us/op 1.11
nodejs block root to RootHex using the deprecated toHexString 470.29 ns/op 486.38 ns/op 0.97
nodejs byteArrayEquals 32 bytes (block root) 25.644 ns/op 25.866 ns/op 0.99
nodejs byteArrayEquals 48 bytes (pubkey) 37.175 ns/op 37.414 ns/op 0.99
nodejs byteArrayEquals 96 bytes (signature) 39.788 ns/op 41.037 ns/op 0.97
nodejs byteArrayEquals 1024 bytes 42.762 ns/op 43.658 ns/op 0.98
nodejs byteArrayEquals 131072 bytes (blob) 1.7286 us/op 1.7615 us/op 0.98
browser block root to RootHex using toHex 144.10 ns/op 147.46 ns/op 0.98
browser block root to RootHex using toRootHex 129.61 ns/op 135.79 ns/op 0.95
browser fromHex(blob) 1.7169 ms/op 1.5818 ms/op 1.09
browser fromHexInto(blob) 738.58 us/op 670.45 us/op 1.10
browser block root to RootHex using the deprecated toHexString 331.62 ns/op 346.46 ns/op 0.96
browser byteArrayEquals 32 bytes (block root) 27.660 ns/op 27.966 ns/op 0.99
browser byteArrayEquals 48 bytes (pubkey) 38.978 ns/op 39.443 ns/op 0.99
browser byteArrayEquals 96 bytes (signature) 72.751 ns/op 73.660 ns/op 0.99
browser byteArrayEquals 1024 bytes 739.85 ns/op 751.59 ns/op 0.98
browser byteArrayEquals 131072 bytes (blob) 93.324 us/op 94.753 us/op 0.98

by benchmarkbot/action

@lodekeeper lodekeeper left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving — this resolves the issue.

I independently reproduced the crash end-to-end first (Kurtosis, latest ethereum-package images — Lodestar v1.41.0 + Lighthouse v8.1.2). It fails with exactly the stack this fixes: TypeError: Cannot read properties of undefined (reading 'withdrawalCredentials') at processWithdrawalRequest.ts:86 ← :40 ← processOperations.ts:82, with the victim pinned one slot behind a finalized block until restart. The call site is unchanged since #7284, so this reproduces on v1.44/v1.45/unstable identically.

Fix review:

  • processWithdrawalRequest.ts!isValidatorKnown(state, validatorIndex) is the correct guard. It matches the existing pattern in processPendingDeposits and restores the spec-mandated silent no-op instead of throwing. isValidatorKnown takes ValidatorIndex | null and narrows, so the null case is still covered by the same check.
  • validator/index.ts (builder-registration filter) — good catch, this is the same shared-pubkeyCache hazard feeding headState.getValidator(...). validatorIndex >= headState.validatorCount is the right bound and returning false (skip the registration) is the correct behavior for a pubkey the head state doesn't hold.
  • Swept the other shared-cache consumers to be sure nothing else is exposed: beacon/state/utils.ts already bounds-checks (>= state.validatorCount); processConsolidationRequest / processDeposit / processPendingDeposits / upgradeStateToGloas all already guard via isPubkeyKnown / isValidatorKnown / an inline bound. No remaining unguarded site.
  • Regression test faithfully reproduces the poisoning: adds the pubkey to the shared cache through a clone at index validators.length, asserts getValidatorIndex resolves it out-of-range for the base state, then that processWithdrawalRequest no-ops without throwing.

CI green across the board. LGTM.

🤖 Generated with AI assistance

@nflaig
nflaig merged commit aa562e6 into unstable Aug 3, 2026
19 checks passed
@nflaig
nflaig deleted the nflaig/validate-cached-validator-indices branch August 3, 2026 09:39
markolazic01 pushed a commit to markolazic01/lodestar that referenced this pull request Aug 3, 2026
@wemeetagain

Copy link
Copy Markdown
Member

🎉 This PR is included in v1.46.0 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

4 participants